#include "stdafx.h"
#include "BrickGameView.h"

#include "GlobalAppData.h"

// gfx
#include "Graphics.h"
#include "RenderingSystem.h"
#include "DeferredPipeline.h"

// physics
#include "PhysicsSystem.h"

// math
#include "Ray.h"

// scene
#include "Camera.h"
#include "SceneLoader.h"
#include "SceneSaver.h"
#include "WorldData.h"

// editor
#include "RenderSettingsGui.h"
#include "Window.h"

#include "RenderSettingsTwBar.h"

#include "Army.h"

#include "Globals.h"

BrickGameView::BrickGameView()
{
	mName = "EditorView View";
}

BrickGameView::~BrickGameView()
{

}

void BrickGameView::loadSceneFromFile( const std::string & file )
{
	View::load();

	mRenderSystem = new mgfx::RenderingSystem;
	mPhysicsSystem = new mphys::PhysicsSystem;

	g_gameScene = new GameScene(*mRenderSystem, *mPhysicsSystem);
	float screenAspect = (float)mcore::GlobalAppData::Instance.ScreenWidth / (float)mcore::GlobalAppData::Instance.ScreenHeight;
	mCamera = &g_gameScene->getCamera();

	mCamera->walk(-230);
	mCamera->setLens(0.25f * PI, screenAspect, 5.0f, 15000.0f);
	mRenderSystem->setProjMatrix(mCamera->proj());

	initGui();

	mscene::loadScene(file, mscene::makeWorldData(g_gameScene, mRenderSystem, mPhysicsSystem));

	g_playerContext = new PlayerContext;
}

void BrickGameView::saveSceneToFile( const std::string & file )
{
	// move to sth like commitAllChanges()
	g_gameScene->commitEditorChanges();

	mscene::SceneSaver::save(file, *g_gameScene);
}

void BrickGameView::startGame()
{
	g_gameScene->init();
}

void BrickGameView::endGame()
{
	g_gameScene->teardown();
}

void BrickGameView::unload()
{
	endGame();

	SAFE_DELETE(g_playerContext);
	SAFE_DELETE(g_onWorldGui);

	SAFE_DELETE(mRenderSettingsGui);

	SAFE_DELETE(g_gameScene);
	SAFE_DELETE(mPhysicsSystem);
	SAFE_DELETE(mRenderSystem);

	View::unload();
}

void BrickGameView::update(float dt)
{ 
	//static float SMALL_DT = 0.0001f;
	//if(mTotalTime == 0.0f)
	//	dt = SMALL_DT;
	//mTotalTime += dt;

	//mPhysicsSystem->update(dt);

	g_gameScene->gameUpdate(dt);
	mRenderSystem->update(dt);
}

void BrickGameView::draw()
{
	mRenderSystem->setViewMatrix(mCamera->view());
	mRenderSystem->setEyePosition(mCamera->position());
	mRenderSystem->setViewFrustum(mCamera->Frustum_);
	mgfx::DeferredPipeline::get().render(mRenderSystem->Data, mRenderSystem->Settings);

	g_onWorldGui->draw(mRenderSystem->Data.ViewProjMatrix, mCamera->up(), mCamera->right());

	mGui->draw();
}

bool BrickGameView::onWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam)
{
	if(sendInputToGUI(msg, wParam, lParam))
	{
		return true;
	}

	g_playerContext->processPlayerInput(input::convertWindowsMsgToEvent(msg, wParam, lParam));

	return false;
}

void BrickGameView::initGui()
{
	mRenderSettingsGui = new medit::RenderSettingsGui(&mRenderSystem->Settings);
	mGui->addChild(*mRenderSettingsGui->GuiWindow);

	medit::showRenderSettingsBar(mRenderSystem->Data, mRenderSystem->Settings);

	g_onWorldGui = new OnWorldGui;
}
